<?php
// @formatter:off
/**
 * @file ct.rules.run.php
 * @author Alejandro Dario Simi
 * @date $Date: 2013-06-22 17:58:11 +0000 (Sat, 22 Jun 2013) $
 *
 * $Id: ct.rules.run.php 83 2013-06-22 17:58:11Z daemonraco@gmail.com $
 * $URL: http://wcomix.googlecode.com/svn/tags/wcomix-1.0.0.1/cron/ct.rules.run.php $
 */
// @formatter:on

class WCRulesRun extends WCCronTool {
	//
	// Public methods.
	public function run($spacer = "") {
		global $wcGroupsHolder;
		global $wcRulesHolder;
		global $wcRuleHooks;
		global $wcOptions;

		echo "{$spacer}Marking action's conflicts:\n";
		$this->updateConflicts("{$spacer}\t");

		if(!$wcOptions->activated("UpdateConflicts")) {
			foreach($wcGroupsHolder->groups() as $group) {
				if(is_readable($group->root)) {
					echo "{$spacer}Checking group '{$group->name}' ({$group->id}):\n";

					//
					// Because rules my depend on other rules, this
					// will keep trying until there's no action done.
					$keepTrying = true;
					$tryCount = 0;
					while($keepTrying) {
						$keepTrying = false;
						$tryCount++;

						foreach($wcRulesHolder->items($group) as $rule) {
							if($wcOptions->activated("Rule") && $rule->id != $wcOptions->value("Rule")) {
								continue;
							}

							if($rule->ok()) {
								$informs = $rule->run($wcOptions->activated("IgnoreConflicts"));

								$showTitle = true;
								foreach($informs as $action) {
									if(isset($action["items"])) {
										if($showTitle) {
											echo "{$spacer}\tRunning rule '{$rule->name}' ({$rule->id}) (actions: ".count($rule->actionsIds()).") (try {$tryCount}):\n";
											$showTitle = false;
										}
										foreach($action["items"] as $info) {
											if($info["status"]) {
												echo "{$spacer}\t\t{$info["action"]}: ".WCColorText::ShellGreen("Ok")."\n";
												$keepTrying = true;
											} else {
												if($info["fatal"]) {
													echo "{$spacer}\t\t{$info["action"]}: ".WCColorText::ShellRed("Failed")."\n";
													if(isset($info["error"])) {
														echo "{$spacer}\t\t\t{$info["error"]}\n";
													}
												} elseif($wcOptions->activated("Warnings")) {
													echo "{$spacer}\t\t{$info["action"]}: ".WCColorText::ShellYellow("Warning")."\n";
													if(isset($info["error"])) {
														echo "{$spacer}\t\t\t{$info["error"]}\n";
													}
												}
											}
										}
									}
								}
							}
						}

						if($keepTrying && $tryCount > 10) {
							echo "{$spacer}\tIt tried to much\n";
							$keepTrying = false;
						}
					}
				}
			}
		}
	}
	public function showHelp($spacer = "") {
		echo "{$spacer}This tool walks through every rule and action and executes it.\n\n";
		echo "{$spacer}Options:\n";
		echo "{$spacer}\t-c, --update-conflicts\n";
		echo "{$spacer}\t\tIt only updates conflicts.\n\n";
		echo "{$spacer}\t-i, --ignore-conflicts\n";
		echo "{$spacer}\t\tRun rules even if they have conflicts.\n\n";
		echo "{$spacer}\t-r id, --rule id\n";
		echo "{$spacer}\t\tAnalyses only specified rule id.\n\n";
		echo "{$spacer}\t-w, --warnings\n";
		echo "{$spacer}\t\tActivates warning promptting.\n";
	}
	//
	// Protected methods.
	protected function loadOptions() {
		if(!$this->_optionsLoaded) {
			global $wcOptions;

			if($wcOptions->addOption("Warnings")) {
				$wcOptions->addOptionTrigger("Warnings", "w");
				$wcOptions->addOptionTrigger("Warnings", "warnings");
			}
			if($wcOptions->addOption("IgnoreConflicts")) {
				$wcOptions->addOptionTrigger("IgnoreConflicts", "i");
				$wcOptions->addOptionTrigger("IgnoreConflicts", "ignore-conflicts");
			}
			if($wcOptions->addOption("UpdateConflicts")) {
				$wcOptions->addOptionTrigger("UpdateConflicts", "c");
				$wcOptions->addOptionTrigger("UpdateConflicts", "update-conflicts");
			}
			if($wcOptions->addValueOption("Rule")) {
				$wcOptions->addOptionTrigger("Rule", "r");
				$wcOptions->addOptionTrigger("Rule", "rule");
			}

			$wcOptions->check();

			$this->_optionsLoaded = true;
		}
	}
	protected function updateConflicts($spacer) {
		//
		// Loading global pointers.
		global $wcDefaults;
		global $wcRuleHooks;
		//
		// Checking that Read Only Mode is not activated.
		if(!$wcDefaults["read-only"]) {
			//
			// Un-marking all conflicts in actions.
			echo "{$spacer}Clearing current action conflicts: ";
			$stmt = null;
			$stmtId = __CLASS__."::".__FUNCTION__."[CLEANA]";
			if($this->_db->has($stmtId)) {
				$stmt = $this->_db->get($stmtId);
			} else {
				$query = "update  {$this->_dbprefix}rule_actions\n";
				$query .= "set     rel_ra_conflict = 'N'\n";
				$query .= "where   rel_ra_conflict = 'Y'\n";

				$stmt = $this->_db->prepare($stmtId, $query);
			}
			if($stmt->execute()) {
				echo "{$stmt->rowCount()}\n";
			} else {
				echo "Unable to clean\n";
			}
			//
			// Un-marking all conflicts in rules.
			echo "{$spacer}Clearing current rule conflicts: ";
			$stmt = null;
			$stmtId = __CLASS__."::".__FUNCTION__."[CLEANR]";
			if($this->_db->has($stmtId)) {
				$stmt = $this->_db->get($stmtId);
			} else {
				$query = "update  {$this->_dbprefix}rules\n";
				$query .= "set     rul_conflict = 'N'\n";
				$query .= "where   rul_conflict = 'Y'\n";

				$stmt = $this->_db->prepare($stmtId, $query);
			}
			if($stmt->execute()) {
				echo "{$stmt->rowCount()}\n";
			} else {
				echo "Unable to clean\n";
			}
			//
			// Marking conflicts
			$conflicsTotal = 0;
			echo "{$spacer}Marking action conflicts:\n";
			foreach($wcRuleHooks as $hookId => $hook) {
				if(isset($hook["conficts"])) {
					$conflics = 0;
					echo "{$spacer}\tMarking action conflicts of '{$hook["name"]}' ('{$hookId}'): ";
					eval("\$conflics+={$hook["conficts"]}();");
					$conflicsTotal += $conflics;
					echo "{$conflics}\n";
				}
			}
			echo "{$spacer}Total of conflicts found: {$conflicsTotal}\n";
			//
			// Marking all rules in conflict.
			echo "{$spacer}Marking rule conflicts: ";
			$stmt = null;
			$stmtId = __CLASS__."::".__FUNCTION__."[UPDATER]";
			if($this->_db->has($stmtId)) {
				$stmt = $this->_db->get($stmtId);
			} else {
				$query = "update  {$this->_dbprefix}rules\n";
				$query .= "set     rul_conflict = 'Y'\n";
				$query .= "where   rul_id in (\n";
				$query .= "                select  distinct(rel_ra_rule)\n";
				$query .= "                from    {$this->_dbprefix}rule_actions\n";
				$query .= "                where   rel_ra_conflict = 'Y')\n";

				$stmt = $this->_db->prepare($stmtId, $query);
			}
			if($stmt->execute()) {
				echo "{$stmt->rowCount()}\n";
			} else {
				echo "Unable to update\n";
			}
			//
			// Marking empty rules as in conflict.
			echo "{$spacer}Marking empty rules: ";
			$stmt = null;
			$stmtId = __CLASS__."::".__FUNCTION__."[EMPTYR]";
			if($this->_db->has($stmtId)) {
				$stmt = $this->_db->get($stmtId);
			} else {
				$query = "update  {$this->_dbprefix}rules\n";
				$query .= "set     rul_conflict = 'Y'\n";
				$query .= "where   rul_id not in (\n";
				$query .= "                select  distinct(rel_ra_rule)\n";
				$query .= "                from    {$this->_dbprefix}rule_actions)\n";

				$stmt = $this->_db->prepare($stmtId, $query);
			}
			if($stmt->execute()) {
				echo "{$stmt->rowCount()}\n";
			} else {
				echo "Unable to update\n";
			}
		} else {
			echo "{$spacer}".WCColorText::ShellYellow("ReadOnlyMode activated.\n");
		}
	}
}
?>